package com.jinsilu.freight.ui.activity;

import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.TypedValue;
import android.view.View;
import android.view.animation.AnimationUtils;

import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView;

import com.blankj.utilcode.util.LogUtils;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.hjq.base.BaseAdapter;
import com.hjq.base.BaseVBActivity;
import com.hjq.permissions.Permission;
import com.hjq.permissions.XXPermissions;
import com.jinsilu.freight.R;
import com.jinsilu.freight.action.StatusAction;
import com.jinsilu.freight.aop.DebugLog;
import com.jinsilu.freight.aop.Permissions;
import com.jinsilu.freight.aop.SingleClick;
import com.jinsilu.freight.common.MyActivity;
import com.jinsilu.freight.other.GridSpaceDecoration;
import com.jinsilu.freight.other.IntentKey;
import com.jinsilu.freight.ui.adapter.ImageSelectAdapter;
import com.jinsilu.freight.ui.dialog.AlbumDialog;
import com.jinsilu.freight.widget.HintLayout;
import com.wildma.idcardcamera.camera.IDCardCamera;
import com.yalantis.ucrop.UCrop;
import com.yalantis.ucrop.UCropActivity;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.Set;

import top.zibin.luban.Luban;
import top.zibin.luban.OnCompressListener;

//import com.wildma.idcardcamera.camera.IDCardCamera;

/**
 * author : Android 轮子哥
 * github : https://github.com/getActivity/AndroidProject
 * time   : 2019/07/24
 * desc   : 选择图片
 */
public final class ImageSelectVBActivity extends MyActivity
        implements StatusAction, Runnable,
        BaseAdapter.OnItemClickListener,
        BaseAdapter.OnItemLongClickListener,
        BaseAdapter.OnChildClickListener {

    public static void start(MyActivity activity, OnPhotoSelectListener listener) {
        start(activity, 1, -1, listener);
    }

    @DebugLog
    @Permissions({Permission.READ_EXTERNAL_STORAGE, Permission.WRITE_EXTERNAL_STORAGE})
    public static void start(MyActivity activity, int maxSelect, int mIdCard, OnPhotoSelectListener listener) {
        if (maxSelect < 1) {
            // 最少要选择一个图片
            throw new IllegalArgumentException("are you ok?");
        }
        Intent intent = new Intent(activity, ImageSelectVBActivity.class);
        intent.putExtra(IntentKey.AMOUNT, maxSelect);
        intent.putExtra(IntentKey.IDENTITY, mIdCard);
        activity.startActivityForResult(intent, (resultCode, data) -> {

            if (listener == null || data == null) {
                return;
            }

            if (resultCode == RESULT_OK) {
                compressImage(activity, listener, data);
            } else {
                listener.onCancel();
            }
        });
    }

    public static void start(BaseVBActivity activity, OnPhotoSelectListener listener) {
        start(activity, 1, -1, listener);
    }

    @DebugLog
    @Permissions({Permission.READ_EXTERNAL_STORAGE, Permission.WRITE_EXTERNAL_STORAGE})
    public static void start(BaseVBActivity activity, int maxSelect, int mIdCard, OnPhotoSelectListener listener) {
        if (maxSelect < 1) {
            // 最少要选择一个图片
            throw new IllegalArgumentException("are you ok?");
        }
        Intent intent = new Intent(activity, ImageSelectVBActivity.class);
        intent.putExtra(IntentKey.AMOUNT, maxSelect);
        intent.putExtra(IntentKey.IDENTITY, mIdCard);
        activity.startActivityForResult(intent, (resultCode, data) -> {

            if (listener == null || data == null) {
                return;
            }

            if (resultCode == RESULT_OK) {
                compressImage(activity, listener, data);
            } else {
                listener.onCancel();
            }
        });
    }

    private static void compressImage(Context activity, OnPhotoSelectListener listener, Intent data) {
        Luban.with(activity)
                .load(data.getStringArrayListExtra(IntentKey.IMAGE))
                .ignoreBy(100)
                .filter(path -> !(TextUtils.isEmpty(path) || path.toLowerCase().endsWith(".gif")))
                .setCompressListener(new OnCompressListener() {
                    @Override
                    public void onStart() {
                        // 压缩开始前调用，可以在方法内启动 loading UI
                    }

                    @Override
                    public void onSuccess(File file) {
                        // 压缩成功后调用，返回压缩后的图片文件
                        listener.onSelected(file);
                    }

                    @Override
                    public void onError(Throwable e) {
                        // 当压缩过程出现问题时调用
                        LogUtils.e(e.getMessage());
                    }
                }).launch();
    }

    private static void compressImage(Context activity, OnPhotoSelectListener listener, Uri data) {
        Luban.with(activity)
                .load(data)
                .ignoreBy(100)
                .filter(path -> !(TextUtils.isEmpty(path) || path.toLowerCase().endsWith(".gif")))
                .setCompressListener(new OnCompressListener() {
                    @Override
                    public void onStart() {
                        // 压缩开始前调用，可以在方法内启动 loading UI
                    }

                    @Override
                    public void onSuccess(File file) {
                        // 压缩成功后调用，返回压缩后的图片文件
                        listener.onSelected(file);
                    }

                    @Override
                    public void onError(Throwable e) {
                        // 当压缩过程出现问题时调用
                        LogUtils.e(e.getMessage());
                    }
                }).launch();
    }

    /**
     * 创建一个拍照图片文件对象
     */
    @SuppressWarnings("ResultOfMethodCallIgnored")
    private static File createCameraFile(boolean video) {
        File folder = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), "Camera");
        if (!folder.exists() || !folder.isDirectory()) {
            if (!folder.mkdirs()) {
                folder = Environment.getExternalStorageDirectory();
            }
        }

        try {
            File file = new File(folder, (video ? "IMG_" : "VID") + new SimpleDateFormat("_yyyyMMdd_HHmmss.", Locale.getDefault()).format(new Date()) + (video ? "mp4" : "jpg"));
            file.createNewFile();
            return file;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    private HintLayout mHintLayout;
    private RecyclerView mRecyclerView;
    private FloatingActionButton mFloatingView;

    private ImageSelectAdapter mAdapter;

    /**
     * 身份证图片选择 -1 - 不是身份证 0 - 证面 1 - 反面
     */
    private int mIdCard = 0;

    /**
     * 最大选中
     */
    private int mMaxSelect = 1;
    /**
     * 选中列表
     */
    private final ArrayList<String> mSelectImage = new ArrayList<>();

    /**
     * 全部图片
     */
    private final ArrayList<String> mAllImage = new ArrayList<>();
    /**
     * 图片专辑
     */
    private final HashMap<String, List<String>> mAllAlbum = new HashMap<>();

    @Override
    protected int getLayoutId() {
        return R.layout.image_select_activity;
    }

    @Override
    protected void initView() {
        mHintLayout = findViewById(R.id.hl_image_select_hint);
        mRecyclerView = findViewById(R.id.rv_image_select_list);
        mFloatingView = findViewById(R.id.fab_image_select_floating);
        setOnClickListener(mFloatingView);

        mAdapter = new ImageSelectAdapter(this, mSelectImage);
        mAdapter.setOnChildClickListener(R.id.fl_image_select_check, this);
        mAdapter.setOnItemClickListener(this);
        mAdapter.setOnItemLongClickListener(this);
        mRecyclerView.setAdapter(mAdapter);
        // 禁用动画效果
        mRecyclerView.setItemAnimator(null);
        // 添加分割线
        mRecyclerView.addItemDecoration(new GridSpaceDecoration((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 3, getResources().getDisplayMetrics())));
    }

    @SuppressWarnings("all")
    @Override
    protected void initData() {
        // 获取最大的选择数
        mMaxSelect = getInt(IntentKey.AMOUNT, mMaxSelect);
        mIdCard = getInt(IntentKey.IDENTITY, mIdCard);
        // 显示加载进度条
        showLoading();
        // 加载图片列表
        new Thread(ImageSelectVBActivity.this).start();
    }

    @Override
    public HintLayout getHintLayout() {
        return mHintLayout;
    }

    @SingleClick
    @Override
    public void onRightClick(View v) {
        if (mAllImage.isEmpty()) {
            return;
        }

        ArrayList<AlbumDialog.AlbumInfo> data = new ArrayList<>(mAllAlbum.size() + 1);
        data.add(new AlbumDialog.AlbumInfo(mAllImage.get(0), getString(R.string.image_select_all), String.format(getString(R.string.image_select_total), mAllAlbum.size()), mAdapter.getData() == mAllImage));
        Set<String> keys = mAllAlbum.keySet();
        for (String key : keys) {
            List<String> temp = mAllAlbum.get(key);
            if (temp != null && !temp.isEmpty()) {
                data.add(new AlbumDialog.AlbumInfo(temp.get(0), key, String.format(getString(R.string.image_select_total), temp.size()), mAdapter.getData() == temp));
            }
        }

        new AlbumDialog.Builder(this)
                .setData(data)
                .setListener((dialog, position, bean) -> {

                    setRightTitle(bean.getName());
                    // 滚动回第一个位置
                    mRecyclerView.scrollToPosition(0);
                    if (position == 0) {
                        mAdapter.setData(mAllImage);
                    } else {
                        mAdapter.setData(mAllAlbum.get(bean.getName()));
                    }
                    // 执行列表动画
                    mRecyclerView.setLayoutAnimation(AnimationUtils.loadLayoutAnimation(getActivity(), R.anim.from_right_layout));
                    mRecyclerView.scheduleLayoutAnimation();
                })
                .show();
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        // 遍历判断选择了的图片是否被删除了
        for (String path : mSelectImage) {
            File file = new File(path);
            if (!file.isFile()) {

                mSelectImage.remove(path);
                mAllImage.remove(path);

                File parentFile = file.getParentFile();
                if (parentFile != null) {
                    List<String> data = mAllAlbum.get(parentFile.getName());
                    if (data != null) {
                        data.remove(path);
                    }
                    mAdapter.notifyDataSetChanged();

                    if (mSelectImage.isEmpty()) {
                        mFloatingView.setImageResource(R.drawable.camera_ic);
                    } else {
                        mFloatingView.setImageResource(R.drawable.succeed_ic);
                    }
                }
            }
        }
    }

    @SingleClick
    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.fab_image_select_floating) {
            if (mSelectImage.isEmpty()) {
                if (-1 == mIdCard) {
                    // 点击拍照
                    CameraActivity.start(this, file -> {

                        // 当前选中图片的数量必须小于最大选中数
                        if (mSelectImage.size() < mMaxSelect) {
                            mSelectImage.add(file.getPath());
                        }
                        cropImage(new Intent().putStringArrayListExtra(IntentKey.IMAGE, mSelectImage));
                        // 这里需要延迟刷新，否则可能会找不到拍照的图片
//                        postDelayed(() -> {
//                            // 重新加载图片列表
//                            new Thread(ImageSelectVBActivity.this).start();
//                        }, 1000);
                    });
                } else if (0 == mIdCard) {
                    IDCardCamera.create(this).openCamera(IDCardCamera.TYPE_IDCARD_FRONT);
                } else if (1 == mIdCard) {
                    IDCardCamera.create(this).openCamera(IDCardCamera.TYPE_IDCARD_BACK);
                }
            } else {
                // 完成选择
//                setResult(RESULT_OK, new Intent().putStringArrayListExtra(IntentKey.IMAGE, mSelectImage));
//                finish();
                cropImage(new Intent().putStringArrayListExtra(IntentKey.IMAGE, mSelectImage));
            }
        }
    }

    private void cropImage(Intent data) {
        Uri sourceUri = Uri.fromFile(new File(Objects.requireNonNull(data.getStringArrayListExtra(IntentKey.IMAGE)).get(0)));
        Uri destinationUri = Uri.fromFile(createCameraFile(false));
        UCrop.Options options = new UCrop.Options();
        //是否隐藏底部容器，默认显示
        options.setHideBottomControls(true);
        options.setFreeStyleCropEnabled(false);
        //是否显示裁剪框网格
        options.setShowCropGrid(false);
        options.setCompressionFormat(Bitmap.CompressFormat.WEBP);
        options.setImageToCropBoundsAnimDuration(666);
        options.setToolbarWidgetColor(ContextCompat.getColor(getContext(), R.color.white));
        options.setToolbarColor(this.getResources().getColor(R.color.colorPrimary));
        options.setStatusBarColor(this.getResources().getColor(R.color.colorPrimary));
        options.setAllowedGestures(UCropActivity.SCALE, UCropActivity.NONE, UCropActivity.ALL);
//        UCrop.of(sourceUri, destinationUri)
//                .withOptions(options)
//                .withAspectRatio(16,9)
//                .useSourceImageAspectRatio()
//                .start(this);
        UCrop uCrop = UCrop.of(sourceUri, destinationUri)
                .withOptions(options)
//                .withAspectRatio(8.56f,5.4f);
                .useSourceImageAspectRatio();
        //跳转到我们的activity，而不是用uCrop自带的跳转到UCropActivity
        Intent uCropIntent = uCrop.getIntent(this);
        uCropIntent.setClass(this, com.jinsilu.freight.ui.activity.UCropActivity.class);
        startActivityForResult(uCropIntent,UCrop.REQUEST_CROP);
    }

    /**
     * {@link BaseAdapter.OnItemClickListener}
     *
     * @param recyclerView RecyclerView对象
     * @param itemView     被点击的条目对象
     * @param position     被点击的条目位置
     */
    @Override
    public void onItemClick(RecyclerView recyclerView, View itemView, int position) {
        if (mSelectImage.contains(mAdapter.getItem(position))) {
            ImagePreviewActivity.start(getActivity(), mSelectImage, mSelectImage.indexOf(mAdapter.getItem(position)));
        } else {
            ImagePreviewActivity.start(getActivity(), mAdapter.getItem(position));
        }
    }

    /**
     * {@link BaseAdapter.OnItemLongClickListener}
     *
     * @param recyclerView RecyclerView对象
     * @param itemView     被点击的条目对象
     * @param position     被点击的条目位置
     */
    @Override
    public boolean onItemLongClick(RecyclerView recyclerView, View itemView, int position) {
        if (mSelectImage.size() < mMaxSelect) {
            // 长按的时候模拟选中
            return itemView.findViewById(R.id.fl_image_select_check).performClick();
        } else {
            return false;
        }
    }

    /**
     * {@link BaseAdapter.OnChildClickListener}
     *
     * @param recyclerView RecyclerView对象
     * @param childView    被点击的条目子 View Id
     * @param position     被点击的条目位置
     */
    @Override
    public void onChildClick(RecyclerView recyclerView, View childView, int position) {
        if (childView.getId() == R.id.fl_image_select_check) {
            if (mSelectImage.contains(mAdapter.getItem(position))) {
                mSelectImage.remove(mAdapter.getItem(position));

                if (mSelectImage.isEmpty()) {
                    mFloatingView.hide();
                    postDelayed(() -> {
                        mFloatingView.setImageResource(R.drawable.camera_ic);
                        mFloatingView.show();
                    }, 200);
                }

            } else {

                if (mMaxSelect == 1 && mSelectImage.size() == 1) {

                    List<String> data = mAdapter.getData();
                    if (data != null) {
                        int index = data.indexOf(mSelectImage.get(0));
                        if (index != -1) {
                            mSelectImage.remove(0);
                            mAdapter.notifyItemChanged(index);
                        }
                    }
                    mSelectImage.add(mAdapter.getItem(position));

                } else if (mSelectImage.size() < mMaxSelect) {

                    mSelectImage.add(mAdapter.getItem(position));

                    if (mSelectImage.size() == 1) {
                        mFloatingView.hide();
                        postDelayed(() -> {
                            mFloatingView.setImageResource(R.drawable.succeed_ic);
                            mFloatingView.show();
                        }, 200);
                    }
                } else {
                    toast(String.format(getString(R.string.image_select_max_hint), mMaxSelect));
                }
            }
            mAdapter.notifyItemChanged(position);
        }
    }

    @Override
    public void run() {
        mAllAlbum.clear();
        mAllImage.clear();

        final Uri contentUri = MediaStore.Files.getContentUri("external");
        final String sortOrder = MediaStore.Files.FileColumns.DATE_MODIFIED + " DESC";
        final String selection = "(" + MediaStore.Files.FileColumns.MEDIA_TYPE + "=?)" + " AND " + MediaStore.MediaColumns.SIZE + ">0";

        ContentResolver contentResolver = getContentResolver();
        String[] projections = new String[]{MediaStore.Files.FileColumns._ID, MediaStore.MediaColumns.DATA,
                MediaStore.MediaColumns.DISPLAY_NAME, MediaStore.MediaColumns.DATE_MODIFIED,
                MediaStore.MediaColumns.MIME_TYPE, MediaStore.MediaColumns.WIDTH,
                MediaStore.MediaColumns.HEIGHT, MediaStore.MediaColumns.SIZE};

        Cursor cursor = null;
        if (XXPermissions.isGranted(this, Permission.READ_EXTERNAL_STORAGE)) {
            cursor = contentResolver.query(contentUri, projections, selection, new String[]{String.valueOf(MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE)}, sortOrder);
        }
        if (cursor != null && cursor.moveToFirst()) {

            int pathIndex = cursor.getColumnIndex(MediaStore.MediaColumns.DATA);
            int mimeTypeIndex = cursor.getColumnIndex(MediaStore.MediaColumns.MIME_TYPE);
            int sizeIndex = cursor.getColumnIndex(MediaStore.MediaColumns.SIZE);

            do {
                long size = cursor.getLong(sizeIndex);
                // 图片大小不得小于 10 KB
                if (size < 1024 * 10) {
                    continue;
                }

                String type = cursor.getString(mimeTypeIndex);
                String path = cursor.getString(pathIndex);
                if (TextUtils.isEmpty(path) || TextUtils.isEmpty(type)) {
                    continue;
                }

                File file = new File(path);
                if (!file.exists() || !file.isFile()) {
                    continue;
                }

                File parentFile = file.getParentFile();
                if (parentFile != null) {
                    // 获取目录名作为专辑名称
                    String albumName = parentFile.getName();
                    List<String> data = mAllAlbum.get(albumName);
                    if (data == null) {
                        data = new ArrayList<>();
                        mAllAlbum.put(albumName, data);
                    }
                    data.add(path);
                    mAllImage.add(path);
                }

            } while (cursor.moveToNext());

            cursor.close();
        }

        postDelayed(() -> {
            // 滚动回第一个位置
            mRecyclerView.scrollToPosition(0);
            // 设置新的列表数据
            mAdapter.setData(mAllImage);

            if (mSelectImage.isEmpty()) {
                mFloatingView.setImageResource(R.drawable.camera_ic);
            } else {
                mFloatingView.setImageResource(R.drawable.succeed_ic);
            }

            // 执行列表动画
            mRecyclerView.setLayoutAnimation(AnimationUtils.loadLayoutAnimation(getActivity(), R.anim.fall_down_layout));
            mRecyclerView.scheduleLayoutAnimation();

            // 设置右标提
            setRightTitle(R.string.image_select_all);

            if (mAllImage.isEmpty()) {
                // 显示空布局
                showEmpty();
            } else {
                // 显示加载完成
                showComplete();
            }
        }, 500);
    }

    /**
     * 图片选择监听
     */
    public interface OnPhotoSelectListener {

        /**
         * 选择回调
         *
         * @param file 图片
         */
        void onSelected(File file);

        /**
         * 取消回调
         */
        default void onCancel() {
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == IDCardCamera.RESULT_CODE) {
            //获取图片路径，显示图片
            final String path = IDCardCamera.getImagePath(data);
            if (!TextUtils.isEmpty(path)) {
                // 当前选中图片的数量必须小于最大选中数
                if (mSelectImage.size() < mMaxSelect) {
                    mSelectImage.add(path);
                }
                cropImage(new Intent().putStringArrayListExtra(IntentKey.IMAGE, mSelectImage));
            }
        }
        if (resultCode == RESULT_OK && requestCode == UCrop.REQUEST_CROP) {
            if (data != null) {
                final Uri resultUri = UCrop.getOutput(data);
                // 完成选择
                // 当前选中图片的数量必须小于最大选中数
                if (mSelectImage.size() < mMaxSelect) {
                    mSelectImage.add(resultUri.getPath());
                }
                setResult(RESULT_OK, new Intent().putStringArrayListExtra(IntentKey.IMAGE, mSelectImage));
                finish();
            }
        } else if (resultCode == UCrop.RESULT_ERROR) {
            final Throwable cropError;
            if (data != null) {
                cropError = UCrop.getError(data);
                toast(cropError != null ? cropError.getMessage() : "裁剪失败");
            }
        }
    }
}